package com.robotic.sensor.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/**
 * 温度传感器数据解析工具类
 * 提供HSA系列温度传感器数据格式转换和校验功能
 */
public class TemperatureDataParser {
    
    private static final Logger log = LoggerFactory.getLogger(TemperatureDataParser.class);
    
    // 温度数据转换常量
    private static final int TEMPERATURE_SCALE = 100;  // 温度数据缩放因子
    private static final int EMISSION_SCALE = 1000;    // 发射率数据缩放因子
    
    // 数据范围常量
    private static final BigDecimal MIN_TEMPERATURE = BigDecimal.valueOf(-40);    // 最小温度
    private static final BigDecimal MAX_TEMPERATURE = BigDecimal.valueOf(1000);   // 最大温度
    private static final BigDecimal MIN_EMISSION_RATE = BigDecimal.valueOf(0.001); // 最小发射率
    private static final BigDecimal MAX_EMISSION_RATE = BigDecimal.valueOf(1.200); // 最大发射率
    
    /**
     * 解析温度数据
     * 将2字节原始数据转换为温度值（°C）
     * 
     * @param rawData 原始数据字节数组
     * @return 温度值，失败返回null
     */
    public static BigDecimal parseTemperature(byte[] rawData) {
        try {
            if (rawData == null || rawData.length < 2) {
                log.error("温度数据长度不足，需要2字节");
                return null;
            }
            
            // 将字节数组转换为整数（大端序）
            int rawValue = ((rawData[0] & 0xFF) << 8) | (rawData[1] & 0xFF);
            
            // 转换为温度值（除以100）
            BigDecimal temperature = BigDecimal.valueOf(rawValue)
                    .divide(BigDecimal.valueOf(TEMPERATURE_SCALE), 1, RoundingMode.HALF_UP);
            
            // 验证温度范围
            if (isValidTemperature(temperature)) {
                log.debug("解析温度数据成功: 原始值={}, 温度={}°C", rawValue, temperature);
                return temperature;
            } else {
                log.warn("温度数据超出有效范围: {}°C", temperature);
                return temperature; // 仍然返回数据，但记录警告
            }
            
        } catch (Exception e) {
            log.error("解析温度数据异常: {}", e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 解析发射率数据
     * 将2字节原始数据转换为发射率值
     * 
     * @param rawData 原始数据字节数组
     * @return 发射率值，失败返回null
     */
    public static BigDecimal parseEmissionRate(byte[] rawData) {
        try {
            if (rawData == null || rawData.length < 2) {
                log.error("发射率数据长度不足，需要2字节");
                return null;
            }
            
            // 将字节数组转换为整数（大端序）
            int rawValue = ((rawData[0] & 0xFF) << 8) | (rawData[1] & 0xFF);
            
            // 转换为发射率值（除以1000）
            BigDecimal emissionRate = BigDecimal.valueOf(rawValue)
                    .divide(BigDecimal.valueOf(EMISSION_SCALE), 3, RoundingMode.HALF_UP);
            
            // 验证发射率范围
            if (isValidEmissionRate(emissionRate)) {
                log.debug("解析发射率数据成功: 原始值={}, 发射率={}", rawValue, emissionRate);
                return emissionRate;
            } else {
                log.warn("发射率数据超出有效范围: {}", emissionRate);
                return emissionRate; // 仍然返回数据，但记录警告
            }
            
        } catch (Exception e) {
            log.error("解析发射率数据异常: {}", e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 解析设备ID数据
     * 将2字节原始数据转换为设备ID
     * 
     * @param rawData 原始数据字节数组
     * @return 设备ID，失败返回null
     */
    public static Integer parseDeviceId(byte[] rawData) {
        try {
            if (rawData == null || rawData.length < 2) {
                log.error("设备ID数据长度不足，需要2字节");
                return null;
            }
            
            // 将字节数组转换为整数（大端序）
            int deviceId = ((rawData[0] & 0xFF) << 8) | (rawData[1] & 0xFF);
            
            // 验证设备ID范围（1-247）
            if (deviceId >= 1 && deviceId <= 247) {
                log.debug("解析设备ID成功: {}", deviceId);
                return deviceId;
            } else {
                log.warn("设备ID超出有效范围(1-247): {}", deviceId);
                return deviceId; // 仍然返回数据，但记录警告
            }
            
        } catch (Exception e) {
            log.error("解析设备ID异常: {}", e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 将温度值转换为原始数据
     * 用于写入寄存器
     * 
     * @param temperature 温度值
     * @return 原始数据字节数组
     */
    public static byte[] temperatureToRawData(BigDecimal temperature) {
        try {
            if (temperature == null) {
                log.error("温度值不能为空");
                return null;
            }
            
            // 转换为整数（乘以100）
            int rawValue = temperature.multiply(BigDecimal.valueOf(TEMPERATURE_SCALE)).intValue();
            
            // 转换为字节数组（大端序）
            byte[] rawData = new byte[2];
            rawData[0] = (byte) (rawValue >> 8);
            rawData[1] = (byte) (rawValue & 0xFF);
            
            log.debug("温度值转换为原始数据: {}°C -> {}", temperature, rawValue);
            return rawData;
            
        } catch (Exception e) {
            log.error("温度值转换异常: {}", e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 将发射率值转换为原始数据
     * 用于写入寄存器
     * 
     * @param emissionRate 发射率值
     * @return 原始数据字节数组
     */
    public static byte[] emissionRateToRawData(BigDecimal emissionRate) {
        try {
            if (emissionRate == null) {
                log.error("发射率值不能为空");
                return null;
            }
            
            // 验证发射率范围
            if (!isValidEmissionRate(emissionRate)) {
                log.error("发射率超出有效范围(0.001-1.200): {}", emissionRate);
                return null;
            }
            
            // 转换为整数（乘以1000）
            int rawValue = emissionRate.multiply(BigDecimal.valueOf(EMISSION_SCALE)).intValue();
            
            // 转换为字节数组（大端序）
            byte[] rawData = new byte[2];
            rawData[0] = (byte) (rawValue >> 8);
            rawData[1] = (byte) (rawValue & 0xFF);
            
            log.debug("发射率值转换为原始数据: {} -> {}", emissionRate, rawValue);
            return rawData;
            
        } catch (Exception e) {
            log.error("发射率值转换异常: {}", e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 验证温度值是否在有效范围内
     * 
     * @param temperature 温度值
     * @return 是否有效
     */
    public static boolean isValidTemperature(BigDecimal temperature) {
        if (temperature == null) {
            return false;
        }
        return temperature.compareTo(MIN_TEMPERATURE) >= 0 && 
               temperature.compareTo(MAX_TEMPERATURE) <= 0;
    }
    
    /**
     * 验证发射率值是否在有效范围内
     * 
     * @param emissionRate 发射率值
     * @return 是否有效
     */
    public static boolean isValidEmissionRate(BigDecimal emissionRate) {
        if (emissionRate == null) {
            return false;
        }
        return emissionRate.compareTo(MIN_EMISSION_RATE) >= 0 && 
               emissionRate.compareTo(MAX_EMISSION_RATE) <= 0;
    }
    
    /**
     * 验证设备ID是否在有效范围内
     * 
     * @param deviceId 设备ID
     * @return 是否有效
     */
    public static boolean isValidDeviceId(Integer deviceId) {
        if (deviceId == null) {
            return false;
        }
        return deviceId >= 1 && deviceId <= 247;
    }
    
    /**
     * 格式化温度显示
     * 
     * @param temperature 温度值
     * @return 格式化的温度字符串
     */
    public static String formatTemperature(BigDecimal temperature) {
        if (temperature == null) {
            return "N/A";
        }
        return temperature.setScale(1, RoundingMode.HALF_UP) + "°C";
    }
    
    /**
     * 格式化发射率显示
     * 
     * @param emissionRate 发射率值
     * @return 格式化的发射率字符串
     */
    public static String formatEmissionRate(BigDecimal emissionRate) {
        if (emissionRate == null) {
            return "N/A";
        }
        return emissionRate.setScale(3, RoundingMode.HALF_UP).toString();
    }
    
    /**
     * 字节数组转十六进制字符串
     * 用于调试和日志输出
     * 
     * @param bytes 字节数组
     * @return 十六进制字符串
     */
    public static String bytesToHex(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return "";
        }
        
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X ", b));
        }
        return sb.toString().trim();
    }
    
    /**
     * 十六进制字符串转字节数组
     * 用于测试和调试
     * 
     * @param hex 十六进制字符串
     * @return 字节数组
     */
    public static byte[] hexToBytes(String hex) {
        try {
            if (hex == null || hex.isEmpty()) {
                return new byte[0];
            }
            
            // 移除空格和其他分隔符
            hex = hex.replaceAll("[^0-9A-Fa-f]", "");
            
            if (hex.length() % 2 != 0) {
                throw new IllegalArgumentException("十六进制字符串长度必须为偶数");
            }
            
            byte[] bytes = new byte[hex.length() / 2];
            for (int i = 0; i < bytes.length; i++) {
                bytes[i] = (byte) Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16);
            }
            
            return bytes;
            
        } catch (Exception e) {
            log.error("十六进制字符串转换异常: {}", e.getMessage(), e);
            return new byte[0];
        }
    }
    
    /**
     * 数据质量评估
     * 根据温度值和发射率评估数据质量
     * 
     * @param temperature 温度值
     * @param emissionRate 发射率值
     * @return 数据质量等级（1-5，5为最好）
     */
    public static int assessDataQuality(BigDecimal temperature, BigDecimal emissionRate) {
        int quality = 5; // 默认最高质量
        
        // 检查温度范围
        if (!isValidTemperature(temperature)) {
            quality -= 2;
        } else if (temperature.compareTo(BigDecimal.valueOf(-20)) < 0 || 
                   temperature.compareTo(BigDecimal.valueOf(500)) > 0) {
            quality -= 1; // 极端温度降低质量
        }
        
        // 检查发射率
        if (!isValidEmissionRate(emissionRate)) {
            quality -= 2;
        } else if (emissionRate.compareTo(BigDecimal.valueOf(0.1)) < 0 || 
                   emissionRate.compareTo(BigDecimal.valueOf(1.0)) > 0) {
            quality -= 1; // 极端发射率降低质量
        }
        
        return Math.max(1, quality); // 最低质量为1
    }
}